package ch.fhnw.swa.aufgabenverwaltungswa.persistenz;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
 * Entity Klasse einer Aufgabe
 * @author Tobias Neuenschwander
 * @author Benjamin Schatzmann
 * @author Edis Dilji
 * @author Francis Murillo
 */
@Entity
@NamedQueries({
    @NamedQuery(name = "findAllTask", query = "SELECT a FROM Aufgabe a")
})
public class Aufgabe implements Serializable {
    //**************************************************************************
    //Enum
    //**************************************************************************
    /**
     * Enum mit den Prioritaeten einer Aufgabe
     */
    public enum Prioritaet{
        BLOCKER, KRITISCH, MITTEL, TRIVIAL;
        
        //ToString uebeschreiben funktioniert nicht, da das System dann den Enum im UI nicht mehr kennt
        /**
         * Diese Methode gibt den Wert des Enums als String zurueck
         * @return String mit dem Wert des Enums
         */
        public String getStringOfStatus(){
            String reString = "";
            switch(this){
                default:
                    break;
                case BLOCKER:
                    reString = "Blocker";
                    break;
                case KRITISCH:
                    reString = "Kritisch";
                    break;
                case MITTEL:
                    reString = "Mittel";
                    break;
                case TRIVIAL:
                    reString = "Trivial";
                    break;
            }
            return reString;
        }
    }
    
    /**
     * Enum mit dem Status einer Aufgabe
     */
    public enum Status{
        NEU, INBEARBEITUNG, GELOEST, GESCHLOSSEN, WIEDEREROEFFNET, ZURUECKGEWIESEN;
        //ToString uebeschreiben funktioniert nicht, da er dan den Enum im UI nicht mer kennt
        /**
         * Diese Methode gibt den Wert des Enums als String zurueck
         * @return String mit dem Wert der Enums
         */
        public String getStringOfStatus(){
            String reString = "";
            switch(this){
                default:
                    break;
                case NEU:
                    reString = "Neu";
                    break;
                case INBEARBEITUNG:
                    reString = "In Bearbeitung";
                    break;
                case GELOEST:
                    reString = "Gelöst";
                    break;
                case GESCHLOSSEN:
                    reString = "Geschlossen";
                    break;
                case WIEDEREROEFFNET:
                    reString = "Wiedereröffnet";
                    break;
                case ZURUECKGEWIESEN:
                    reString = "Zurückgewiesen";
                    break;
            }
            return reString;
        }
    }
    
    //**************************************************************************
    //Variablen
    //**************************************************************************
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private String beschreibung;
    private String projekt;
    private Aufgabe.Prioritaet prioritaet = Prioritaet.TRIVIAL;
    private Aufgabe.Status status = Status.NEU;
    @Temporal(TemporalType.DATE)
    private Date faelligkeit;
    //kein mappedBy, da die JoinTable sonst nur verändert werden kann, wenn ein mitarbeiter gespeichert wird.
    @ManyToMany
    @JoinTable(name = "jnd_ma_aufg",
    joinColumns = @JoinColumn(name = "aufg_fk"),
    inverseJoinColumns = @JoinColumn(name = "ma_fk"))
    private List<Mitarbeiter> mitarbeiterZugeteilt;

    //**************************************************************************
    //Getter/Setter
    //**************************************************************************
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getBeschreibung() {
        return beschreibung;
    }

    public void setBeschreibung(String beschreibung) {
        this.beschreibung = beschreibung;
    }

    public String getProjekt() {
        return projekt;
    }

    public void setProjekt(String projekt) {
        this.projekt = projekt;
    }

    public Prioritaet getPrioritaet() {
        return prioritaet;
    }

    public void setPrioritaet(Prioritaet prioritaet) {
        this.prioritaet = prioritaet;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    public Date getFaelligkeit() {
        return faelligkeit;
    }

    public void setFaelligkeit(Date faelligkeit) {
        this.faelligkeit = faelligkeit;
    }

    public List<Mitarbeiter> getMitarbeiterZugeteilt() {
        return mitarbeiterZugeteilt;
    }

    public void setMitarbeiterZugeteilt(List<Mitarbeiter> mitarbeiterZugeteilt) {
        this.mitarbeiterZugeteilt = mitarbeiterZugeteilt;
    }

    //**************************************************************************
    //Methoden
    //**************************************************************************
    @Override
    public int hashCode() {
        int hash = 3;
        hash = 23 * hash + (this.id != null ? this.id.hashCode() : 0);
        hash = 23 * hash + (this.name != null ? this.name.hashCode() : 0);
        hash = 23 * hash + (this.beschreibung != null ? this.beschreibung.hashCode() : 0);
        hash = 23 * hash + (this.projekt != null ? this.projekt.hashCode() : 0);
        hash = 23 * hash + (this.prioritaet != null ? this.prioritaet.hashCode() : 0);
        hash = 23 * hash + (this.status != null ? this.status.hashCode() : 0);
        hash = 23 * hash + (this.faelligkeit != null ? this.faelligkeit.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Aufgabe other = (Aufgabe) obj;
        if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
            return false;
        }
        if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
            return false;
        }
        if ((this.beschreibung == null) ? (other.beschreibung != null) : !this.beschreibung.equals(other.beschreibung)) {
            return false;
        }
        if ((this.projekt == null) ? (other.projekt != null) : !this.projekt.equals(other.projekt)) {
            return false;
        }
        if (this.prioritaet != other.prioritaet) {
            return false;
        }
        if (this.status != other.status) {
            return false;
        }
        if (this.faelligkeit != other.faelligkeit && (this.faelligkeit == null || !this.faelligkeit.equals(other.faelligkeit))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "Aufgabe{" + "id=" + id + ", name=" + name + ", beschreibung=" + beschreibung + ", projekt=" + projekt + ", prioritaet=" + prioritaet + ", status=" + status + ", faelligkeit=" + faelligkeit + ", mitarbeiterZugeteilt=" + mitarbeiterZugeteilt + '}';
    }
}
